/*****************************************************************************
文 件 名: work.c
描    述: 1.6代墒情站采集
作    者: 武玉峰
版    本: 1.0
完成日期: 2016.8.19 
修改历史: 
*****************************************************************************/
#ifdef SOIL_MOISTURE_STATION_1_6 
#include "stdio.h"
#include "string.h"
#include "collect.h"
#include "gpio.h"
#include "gprs.h"
#include "rs485.h"
#include "delay.h"
#include "24cxx.h"
#include "timer.h"
#include "adc.h"
#include "usart.h"
#include "config.h"
#include "rtc.h"
#include "sys.h"
#include "fireware_update_extr.h"
 //数据发送到服务器的超时时间，单位0.5秒
#define  SEND_DATA_TO_SERVER_TIMEOUT    30
 //接收缓存区 	
 
//modbus 重发次数
#define MODBUS_RETRY_COUNT 1
 
//485口相关变量
 
extern u8  _485jsok;
extern u16 _Hoped485ByteCounts;  
 
//485接收缓冲区
extern u8 _RS485_RX_BUF[660];  	 
 
//接收到的数据长度
extern u8 _RS485_RX_CNT;
 
 
extern u8        _SIM900_ERR ;
extern u8        _SIM900_ERR_SUM ;
extern u8         _SignalIntensity;
extern u8         _IMEI[16];
extern u8         _CurVersion;
extern u16         _UpdateVersion;
extern Config _Config;
 

extern u16       _Hoped485ByteCounts ;

extern u8        _WorkPattern;
extern u16      _TimeOutCount; 
extern u16       _RecordCount; 
 


u16  _collectedValues[COLLECT_VALUE_SIZE];
 
void CollectData(void);
/*************************************************
函数名称: EnergySavingSwitch
功    能: 节能开关
参    数: flag:0 关闭 1打开          
返 回 值: 无
*************************************************/
void EnergySavingSwitch(u8 flag)
{

     if(flag==1)
 			 RELAY=1;
 		else
 			 RELAY=0;
    
}

 
/*************************************************
函数名称: GetByModbusF3
功    能: 用modbus功能码3读取传感器数据
参    数: address:传感器地址
          databuffer：存放采集结果数据缓冲区的地址
					startRegAddress:要采集的寄存器起始地址
					regCount:要采集的寄存器个数
返 回 值: 是否成功
*************************************************/
s16 GetByModbusF3(u16 *databuffer, u8 address,u16 startRegAddress,u16 regCount)
{
    int k = 0;
    int j = 0;
 
    u8   ModbusCommand[8] = {0};

StartCollect:
    _Hoped485ByteCounts = 7;
    _485jsok = 0;
    BuildModbusMessage(address, 3, startRegAddress, regCount, ModbusCommand);
    DebugOut("send func 3\r\n");
    CONLED = 0;
    memset(_RS485_RX_BUF, '\0', sizeof(_RS485_RX_BUF));
    _RS485_RX_CNT = 0;
    RS485_Send_Data(ModbusCommand, 8); //发送功能码3命令
    _TimeOutCount = 0;
    while(_485jsok == 0)
    {
        IWDG_Feed();
        //if(_WorkPattern == 1)return -1;
        if(_TimeOutCount > 10)
            break;

    }
    CONLED = 1;
    //数据采集成功
    if(_485jsok == 1)
    {
        DebugOut("func 3 sucess\r\n");
        for(j = 0;j<regCount;++j)
					databuffer[j] = (_RS485_RX_BUF[3+2*j] << 8) + _RS485_RX_BUF[3+2*j+1];
 
    }
    else
    {
        DebugOut("func 3 Fail\r\n");
        DelayHalfSecond(4);
        k++;
        if(k <= MODBUS_RETRY_COUNT)
            goto StartCollect;

    }
    DelayHalfSecond(10);
    if(k > MODBUS_RETRY_COUNT)
        return 0;
    else
        return 1;


}

      
/*************************************************
函数名称: GetSoilTemp
功    能: 用modbus功能码3读取土温数据
参    数: address:土温传感器地址
          databuffer：存放采集结果数据缓冲区的地址
返 回 值: 是否成功
*************************************************/
s16 GetSoilTemp(u16 *databuffer, u8 address)
{
    int k = 0;
    int j = 0;
 
    u8   ModbusCommand[8] = {0};

StartCollect:
    _Hoped485ByteCounts = 7;
    _485jsok = 0;
    BuildModbusMessage(address, 3, 0, 1, ModbusCommand);
    DebugOut("send func 3\r\n");
    CONLED = 0;
    memset(_RS485_RX_BUF, '\0', sizeof(_RS485_RX_BUF));
    _RS485_RX_CNT = 0;
    RS485_Send_Data(ModbusCommand, 8); //发送功能码3命令
    _TimeOutCount = 0;
    while(_485jsok == 0)
    {
        IWDG_Feed();
        //if(_WorkPattern == 1)return -1;
        if(_TimeOutCount > 10)
            break;

    }
    CONLED = 1;
    //数据采集成功
    if(_485jsok == 1)
    {
        DebugOut("func 3 sucess\r\n");
        j = 0;
        databuffer[0] = (_RS485_RX_BUF[3+2*j] << 8) + _RS485_RX_BUF[3+2*j+1];
 
    }
    else
    {
        DebugOut("func 3 Fail\r\n");
        DelayHalfSecond(4);
        k++;
        if(k <= 3)
            goto StartCollect;

    }
    DelayHalfSecond(2);
    if(k > 3)
        return 0;
    else
        return 1;


}


/*************************************************
函数名称: GetFrequencyByID
功    能: 采集铜环数据高频是水分数据，低频是盐分数据
参    数: id:铜环ID，杆上铜环从上到下的顺序从0开始。
          f：当前采集的是高频还是低频  1：低频 0：高频
返 回 值: 是否成功
*************************************************/
s16 GetFrequencyByID(u8 id, u8 f)
{


    u8   ModbusCommand[8] = {0};
 
    u8 k;
    u16 value = 0;
    //采集下位机的数据
    memset(_RS485_RX_BUF, 0, sizeof(_RS485_RX_BUF));


 
    k = 0;
SetID:
    //设置铜环ID
    _Hoped485ByteCounts = 8;
    _485jsok = 0;
    BuildModbusMessage(3, 6, 1, id, ModbusCommand);
    DebugOut("send func 6:SetID\r\n");
    CONLED = 0;
    _RS485_RX_CNT = 0;
    RS485_Send_Data(ModbusCommand, 8); //发送功能码6命令
    DelayHalfSecond(10);
    CONLED = 1;
    if(_485jsok == 1)
    {
        DebugOut("func 6 sucess\r\n");
        //发送到232口
        DebugOut("%d %d %d %d %d %d %d %d \r\n", _RS485_RX_BUF[0], _RS485_RX_BUF[1], _RS485_RX_BUF[2], _RS485_RX_BUF[3],
                _RS485_RX_BUF[4], _RS485_RX_BUF[5], _RS485_RX_BUF[6], _RS485_RX_BUF[7]);
    }
    else
    {
        DebugOut("func 6 Fail\r\n");
        DelayHalfSecond(4);
        k++;
        if(k <= 5)
            goto SetID;


    }

    //设置铜环ID为15使铜环节能
   //if(id == 15)return 0;

    _TimeOutCount = 0;
   DelayHalfSecond(3);



    k = 0;
SetFrequency:
    //设置高频或低频
    _Hoped485ByteCounts = 8;
    _485jsok = 0;
    _RS485_RX_CNT = 0;
    BuildModbusMessage(3, 6, 2, f, ModbusCommand);
    if(f == 0)
    {
        DebugOut("send func 6:SetHF\r\n");
    }
    else
    {
        DebugOut("send func 6:SetLF\r\n");
    }

    CONLED = 0;
    RS485_Send_Data(ModbusCommand, 8); //发送功能码6命令
    while(_485jsok == 0)
    {
        IWDG_Feed();
        //if(_WorkPattern == 1)return -1;
        if(_TimeOutCount > 10)
            break;

    }
    CONLED = 1;
    if(_485jsok == 1)
    {
        DebugOut("func 6 sucess\r\n");
        //发送到232口
        DebugOut("%d %d %d %d %d %d %d %d \r\n", _RS485_RX_BUF[0], _RS485_RX_BUF[1], _RS485_RX_BUF[2], _RS485_RX_BUF[3],
              _RS485_RX_BUF[4], _RS485_RX_BUF[5], _RS485_RX_BUF[6], _RS485_RX_BUF[7]);
    }
    else
    {
        DebugOut("func 6 Fail\r\n");
        DelayHalfSecond(4);
        k++;
        if(k <= 5)
            goto SetFrequency;
    }


  
        if(f == 0) //高频为0，低频为1
        {
            //高频延时7秒
           DelayHalfSecond(_Config._HighFreqDelaySpan*2);
        }
        else
        {
            //低频延时10秒
           DelayHalfSecond(_Config._LowFreqDelaySpan*2);
        }
        k=0;
GetFrequency:
    //采集1次
//    for(i = 0; i < 5; ++i)
//    {
        //if(_WorkPattern == 1)return -1;
				_Hoped485ByteCounts = 7;
        _485jsok = 0;
        BuildModbusMessage(3, 3, 3, 1, ModbusCommand);
        DebugOut("send func 3\r\n");
        CONLED = 0;
        memset(_RS485_RX_BUF, 0, sizeof(_RS485_RX_BUF));
        _RS485_RX_CNT = 0;
        RS485_Send_Data(ModbusCommand, 8); //发送功能码6
        DelayHalfSecond(10);
        CONLED = 1;
        //数据采集成功
        if(_485jsok == 1)
        {
            DebugOut("func 3 sucess\r\n");

            DebugOut("%d %d %d %d %d %d %d \r\n", _RS485_RX_BUF[0], _RS485_RX_BUF[1], _RS485_RX_BUF[2], _RS485_RX_BUF[3],
                    _RS485_RX_BUF[4], _RS485_RX_BUF[5], _RS485_RX_BUF[6] );
            value =   (_RS485_RX_BUF[3] << 8) + _RS485_RX_BUF[4];
        }
        else
        {
            DebugOut("func 3 Fail\r\n");
					  DelayHalfSecond(4);
            k++;
            if(k <= 5)
            goto GetFrequency;
        }
        DelayHalfSecond(2);
    //}
    return value;
}
/*************************************************
函数名称: CollectData
功    能: 采集铜环、土温、电压数据，并把结果放入全局变量_collectedValues中
参    数: 无
返 回 值: 无
*************************************************/
void CollectData()
{
           u16 i;
            memset(_collectedValues, 0, sizeof(_collectedValues));	//采集缓存清零
            NETLED = 1;
 

            //打开节能开关 _ATAndESConfig的第二位是节能开关
            if(_Config._EnergySaving==1)
            {
                DebugOut("Fc6: EnergySaving Switch On\r\n");
                EnergySavingSwitch(1);
                DelayHalfSecond(20);
            }

						RELAY1=1;
						DelayHalfSecond(4);
						 DebugOut("Collect Soil Temperature!\r\n");
			
            //采集土温
      if(_Config.IsNewSoilTemp==0)
			{//旧土温
				for(i = 0; i < 16; ++i)
				{
					IWDG_Feed();
					if(_Config._SoilTempConfig & (1 << i))
					{
						DebugOut("\r\ncollect soil temp data level %d\r\n", i + 1);
						GetSoilTemp(&_collectedValues[32+i], i + 4); //土温在_collectedValues中的地址4,5,6,7,8,9,10,11
					}
				}
			}
			else
			{//新土温
				//采集1-8层
			 if((_Config._SoilTempConfig & 0x00ff)!=0)
			 {
				 DebugOut("\r\ncollect 1-8 level soil temp \r\n");
				GetByModbusF3(&_collectedValues[32], _Config.SoilTempAddr1_8,0,8);  
			 }
			 //采集9-10层
			 if(((_Config._SoilTempConfig & 0xff00)>>8)!=0)
			 {
				  DebugOut("\r\ncollect 9-16 level soil temp \r\n");
			   GetByModbusF3(&_collectedValues[40], _Config.SoilTempAddr9_16,0,8);  
			 } 
			}
						
						RELAY1=0;
						
						DebugOut("Collect Coppering!\r\n");
            //采集铜环16层
            for(i = 0; i < 16; ++i)
            {
							  //采集铜环第i层高频,配置的低16个字节
                IWDG_Feed();
          

                if(_Config._HighFreqConfig & (1 << i))
                {
                    DebugOut("\r\ncollect level %d HF\r\n", i + 1);
                     //水分为高频值，第二个参数高频为0，低频为1
                    _collectedValues[i] = GetFrequencyByID(i, 0);
                }
							
							
              
							//采集铜环第i层低频,配置的高16个字节
                IWDG_Feed();
               
                if(_Config._LowFreqConfig & (1 << i))
                {
                    DebugOut("\r\ncollect level %d LF\r\n", i + 1);
                    //盐分为低频值，第二个参数高频为0，低频为1
                    _collectedValues[16+i] = GetFrequencyByID(i, 1);
                } 
            }



            //使铜环节能
//             if(_HighFreqConfig > 0 || _LowFreqConfig>0)
//                 GetFrequencyByID(15, 1);



             //信号强度
						_collectedValues[48] = _SignalIntensity; 
						//采集电压，采集10次取平均
            _collectedValues[49]=Get_Adc_Average(ADC_Channel_6,10); 
						DebugOut("%d\r\n",_collectedValues[49]);
	 

//             if(_EnergySaving==1)
//             {
//                 //关闭节能开关
//                 DebugOut("Close the energy-saving switch\r\n");
//                 EnergySavingSwitch(0);
//             } 
}
#endif
/**********************************************************************************************************************/

